# -*- coding: utf-8 -*-
from pylab import *
class scaledata():
  def __init__(self,ax=None,Yarray=None,Xarray=None,rescale=(False,True),subplot=None):
    self._ind = None
    self.ax = gca() if ax is None else ax
    self.im = gci()
    self.f = gcf()
    canvas = self.ax.figure.canvas
    #canvas = self.ax.figure.canvas
    self.canvas = canvas
    self.gate=False
    self.scale=True
    self.add = True
    if isinteractive():
      canvas.mpl_connect('key_press_event', self.key_press_callback)
    self.mpl_init()
    self.subplotf=subplot
    self.Yarray = Yarray
    self.Xarray = Xarray
    self.rescale=rescale
  def mpl_init(self):
    if not isinteractive():
      return False
    for c in ['c1','c2','c3']:
      if vars(self).has_key(c):
        self.canvas.mpl_disconnect(vars(self)[c])
        del(vars(self)[c])
    if self.scale:
      self.c1 = self.canvas.mpl_connect('button_press_event', self.button_press_callback)
      self.c2 = self.canvas.mpl_connect('button_release_event', self.button_release_callback)
      self.c3 = self.canvas.mpl_connect('motion_notify_event', self.motion_notify_callback)
    else:
      self.c1 = self.canvas.mpl_connect('button_press_event', self.button_press_callback_ploti)
  def button_press_callback_ploti(self, event):
    AXES = self.ax.get_position().get_points()
    i=event.y/float(self.canvas.GetSizeTuple()[1])
    j=event.x/float(self.canvas.GetSizeTuple()[0])
    ext=self.ax.images[0].get_extent()
    im=self.ax.images[0].get_array().data
    if not self.gate:
      J=len(im.T)*(j-ext[0])/(ext[1]-ext[0])
      J = len(im.T)*(j-AXES[0,0])/(AXES[1,0]-AXES[0,0])
    else:  
      print "gate trace"
      I=len(im)*(i-ext[2])/(ext[3]-ext[2])
      J=I
      J = len(im)*(i-AXES[0,1])/(AXES[1,1]-AXES[0,1])
    self.plotdata(int(round(J)))
  def plotdata(self,i):
    self.subplotf = figure() if self.subplotf is None else self.subplotf 
    if len(self.subplotf.axes)==0:
      axes()
    figure(self.subplotf.number);
    oldaxis = axis()
    print i
    self.current_i = i
    im=self.ax.images[0].get_array().data
    ext=self.ax.images[0].get_extent()
    X = self.Xarray if self.Xarray is not None else linspace(ext[0],ext[1],len(im.T))
    Y = self.Yarray if self.Yarray is not None else linspace(ext[2],ext[3],len(im))
    if self.rescale[0]:
      oldaxis = [None,None,oldaxis[2],oldaxis[3]]
    if self.rescale[1]:
      oldaxis = [oldaxis[0],oldaxis[1],None,None]
    if len(gca().lines)>0:
      if shape(gca().lines[0].get_data())[1]<>(len(X) if self.gate else len(Y)):
        gca().lines=[]
        oldaxis=[None]*4
    else:
      oldaxis=[None]*4
    if self.add==False:
      gca().lines=[]
    if not self.gate:
      print X[i]
      plot(Y,im.T[i],label='%.2f' % X[i]) 
      for ax in self.f.axes[3:]:
        for linj in ax.lines:
	  lin=linj.get_data()
	  xs = lin[1][lin[0]==X[i]]
          plot(xs,map(lambda x:im.T[i][argmin(abs(Y-x))],xs),'x')
    else:
      print Y[i]
      plot(X,im[i],label='%.2f' % Y[i])
      for ax in self.f.axes[3:]:
        for linj in ax.lines:
	  lin=linj.get_data()
	  xs = lin[0][lin[1]==Y[i]]
          plot(xs,map(lambda x:im[i][argmin(abs(X-x))],xs),'x')
    axis(tuple(oldaxis))
  def button_press_callback(self, event):
    'whenever a mouse button is pressed'
    if event.inaxes==None: return
    if event.button != 1: return
    if self._ind: return
    self._ind = True # self.get_ind_under_point(event)
    self.zerox,self.zeroy = event.xdata, event.ydata
    try:
      im=self.ax.images[-1]
    except IndexError:
      self.ax=gca()
      if len(self.ax.images)==0:
	print "no image in current axes"
	return 0
      else:
	im=self.ax.images[-1]
    tmpclim = array(im.get_clim())
    self.tmpclimv = tmpclim
    self.dclim = (self.tmpclimv[1]-self.tmpclimv[0])
    Xlim,Ylim=self.ax.get_xlim(),self.ax.get_ylim()
    self.Ysclae,self.Xsclae=(Ylim[1]-Ylim[0]),(Xlim[1]-Xlim[0])
  def button_release_callback(self, event):
    'whenever a mouse button is released'
    if event.button != 1: return
    self._ind = None
  def motion_notify_callback(self, event):
    'on mouse movement'
    if self._ind is None: return
    if event.inaxes is None: return
    if event.button != 1: return
    x,y = event.xdata, event.ydata
    self.dx,self.dy=x-self.zerox,y-self.zeroy
    tmpclim = self.tmpclimv+self.dy * self.dclim / self.Ysclae
    tmpclim = tmpclim+self.dx *array([1,-1])* self.dclim/ self.Xsclae
    #self.tmpclimv = tmpclim
    if tmpclim [0]<tmpclim [1]:
      im=self.ax.images[-1]
      im.set_clim(tmpclim.tolist())
      if isinteractive():
        show();draw()
  def key_press_callback(self, event):
    print 'key "%s" pressed'  % event.key
    if event.key=='w':
      self.scale=self.scale==False
      self.mpl_init()
    elif event.key=='t':
      self.gate=self.gate==False
    elif event.key=='a':
      self.add=self.add==False
    elif event.key=='left':
      self.current_i +=-1
      self.plotdata(self.current_i)
    elif event.key=='right':
      self.current_i += 1
      self.plotdata(self.current_i)

